package com.gitee.dolt.log.event;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.gitee.dolt.core.exception.InternalServerException;
import com.gitee.dolt.enumeration.OptLogOut;
import com.gitee.dolt.log.properties.OptLogFormatter;
import com.gitee.dolt.log.properties.OptLogType;
import com.gitee.dolt.event.OptLogEvent;
import com.gitee.dolt.log.properties.OptLogProperties;
import com.gitee.dolt.model.OptLogDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;

/**
 * 异步监听日志事件
 *
 * @author LYH
 */
@Slf4j
@AllArgsConstructor
public class OptLogListener {

    private OptLogDbHandler optLogDbHandler;
    private OptLogProperties optLogProperties;

    @Async
    @Order
    @EventListener(OptLogEvent.class)
    public void saveSysLog(OptLogEvent event) {
        OptLogDTO optLogDTO = (OptLogDTO) event.getSource();
        if (optLogDTO == null) {
            log.warn("日志对象不存在，忽略操作日志");
            return;
        }

        OptLogType optLogType = null;
        OptLogOut out = event.getOut();
        if (OptLogOut.DEFAULT.equals(out)) {
            optLogType = optLogProperties.getType();
        } else if (OptLogOut.DB.equals(out)) {
            optLogType = OptLogType.DB;
        } else if (OptLogOut.LOGGER.equals(out)) {
            optLogType = OptLogType.LOGGER;
        } else {
            optLogType = OptLogType.ALL;
        }


        if (OptLogType.LOGGER.equals(optLogType) || OptLogType.ALL.equals(optLogType)) {
            if (optLogProperties.getFormatter() == OptLogFormatter.PRETTY) {
                log.debug("{}|{}|\n{}", "OPT_LOG", StrUtil.nullToDefault(optLogDTO.getTrace(), "-"), JSONUtil.toJsonPrettyStr(optLogDTO));
            } else {
                log.debug("{}|{}|{}", "OPT_LOG", StrUtil.nullToDefault(optLogDTO.getTrace(), "-"), JSONUtil.toJsonStr(optLogDTO));
            }
        }
        if (OptLogType.DB.equals(optLogType) || OptLogType.ALL.equals(optLogType)) {
            if (optLogDbHandler == null) {
                throw new InternalServerException("请实现并注入OptLogDbHandler");
            }
            optLogDbHandler.handle(optLogDTO);
        }
    }

}
